package com.piece.file.util;

import com.piece.core.framework.util.math.SequenceUtil;
import com.piece.core.framework.util.basic.SpringUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.framework.util.file.FileUtil;
import com.piece.core.log.config.UserContextHolder;
import com.piece.core.web.util.ServletUtil;
import com.piece.file.model.TbSysFile;
import com.piece.file.service.TbSysFileService;
import com.piece.file.support.WpsResponse;
import com.piece.file.support.FileAcl;
import com.piece.file.support.FileInfo;
import com.piece.file.support.FileUserInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
@RefreshScope
public class WpsUtil {

    @Value("${wps.domain:#{null}}")
    private String domain;

    @Value("${wps.app_id:#{null}}")
    private String app_id;

    @Value("${wps.app_secret:#{null}}")
    private String app_secret;

    @Value("${wps.redirect_key:#{null}}")
    private String redirect_key;

    @Value("${wps.redirect_value:#{null}}")
    private String redirect_value;

    @Value("${spring.resources.context:#{'/'}}")
    protected String contextPath;

    // office
    private static String[] office = {"word", "excel", "ppt"};

    // excel
    private static String[] etExts = {"et", "xls", "xlt", "xlsx", "xlsm", "xltx", "xltm", "csv"};

    // word
    private static String[] wpsExts = {"doc", "docx", "txt", "dot", "wps", "wpt", "dotx", "docm", "dotm"};

    // ppt
    private static String[] wppExts = {"ppt", "pptx", "pptm", "pptm", "ppsm", "pps", "potx", "potm", "dpt", "dps"};

    // pdf
    private static String[] pdfExts = {"pdf"};

    /**
     * 获取预览用URL
     *
     * @param fileUrl    文件url
     * @param checkToken 是否校验token
     */
    public WpsResponse getViewUrl(String fileUrl, boolean checkToken) {
        WpsResponse t = new WpsResponse();
        String fileType = FileUtil.getFileSuffixFromPath(fileUrl);
        String uuid = SequenceUtil.uuid();
        Map<String, String> values = new HashMap<String, String>() {
            {
                put("_w_appid", app_id);
                if (checkToken) {
                    put("_w_tokentype", "1");
                }
                put(redirect_key, redirect_value);
                put("_w_userid", "-1");
                put("_w_filepath", fileUrl);
                put("_w_filetype", "web");
            }
        };

        String wpsUrl = getWpsUrl(values, fileType, uuid);
        t.setToken(uuid);
        t.setExpires_in(600);
        t.setUrl(wpsUrl);
        return t;
    }

    /**
     * 获取预览用URL
     *
     * @param fileId     文件id
     * @param userId     用户id
     * @param checkToken 是否校验token
     */
    public WpsResponse getViewUrl(String fileId, String userId, boolean checkToken) {
        TbSysFileService tbSysFileService = SpringUtil.getBean(TbSysFileService.class);

        TbSysFile tbSysFile = tbSysFileService.findById(fileId);
        if (null != tbSysFile) {
            WpsResponse t = new WpsResponse();
            String fileName = tbSysFile.getServerFileName();
            String fileType = FileUtil.getFileSuffix(fileName);
            String uuid = SequenceUtil.uuid();

            Map<String, String> values = new HashMap<String, String>() {
                {
                    put("_w_appid", app_id);
                    if (checkToken) {
                        put("_w_tokentype", "1");
                    }
                    put(redirect_key, redirect_value);
                    put("_w_filepath", fileName);
                    put("_w_userid", userId);
                    put("_w_filetype", "db");
                }
            };

            String wpsUrl = getWpsUrl(values, fileType, fileId);
            t.setToken(uuid);
            t.setExpires_in(600);
            t.setUrl(wpsUrl);
            return t;
        }
        return null;
    }

    /**
     * 获取文件元数据
     *
     * @param url        文件路径
     * @param fileId     文件ID
     * @param permission 操作权限
     */
    private Map<String, Object> getWebFileInfo(String url, String fileId, String permission) {
        String userId = UserContextHolder.getUserId();
        String userName = UserContextHolder.getUserName();
        String userAvatar = UserContextHolder.getUserAvatar();

        if (StringUtil.isNotEmpty(userAvatar)) {
            userAvatar = ServletUtil.getRequestPrefix(contextPath) + "public/file/download/" +  userAvatar;
        } else {
            userAvatar = "https://zmfiletest.oss-cn-hangzhou.aliyuncs.com/user0.png";
        }
        // 构建默认user信息
        FileUserInfo wpsUser = new FileUserInfo(
                userId, userName, permission, userAvatar
        );

        // 构建文件
        long fileSize = FileUtil.getNetFileSize(url);
        FileInfo fileInfo = new FileInfo(
                fileId, FileUtil.getFileNameFromPath(url),
                1, fileSize, "-1", new Date().getTime(), url,
                new FileAcl()
        );

        return new HashMap<String, Object>() {
            {
                put("file", fileInfo);
                put("user", wpsUser);
            }
        };
    }

    public String getWpsUrl(Map<String, String> values, String fileType, String fileId) {
        String keyValueStr = SignatureUtil.getKeyValueStr(values);
        String signature = SignatureUtil.getSignature(values, app_secret);
        String fileTypeCode = getFileTypeCode(fileType);

        return domain + fileTypeCode + "/" + fileId + "?"
                + keyValueStr + "_w_signature=" + signature;
    }

    /**
     * 创建临时文件
     */
    public String createTemplateFile(String template, String userId) {
        boolean typeTrue = checkCode(template);
        if (typeTrue) {
            return getTemplateWpsUrl(template, userId);
        }
        return "";
    }

    public String getTemplateWpsUrl(String fileType, String userId) {
        Map<String, String> values = new HashMap<String, String>() {
            {
                put(redirect_key, redirect_value);
                put("_w_appid", app_id);
                put("_w_userid", userId);
            }
        };
        String keyValueStr = SignatureUtil.getKeyValueStr(values);
        String signature = SignatureUtil.getSignature(values, app_secret);
        String fileTypeCode = getTypeCode(fileType);

        return domain + fileTypeCode + "/new/0" + "?"
                + keyValueStr + "_w_signature=" + signature;
    }

    public static String getFileTypeCode(String fileType) {
        for (String et : etExts) {
            if (et.equalsIgnoreCase(fileType)) {
                return "s";
            }
        }
        for (String et : wpsExts) {
            if (et.equalsIgnoreCase(fileType)) {
                return "w";
            }
        }
        for (String et : wppExts) {
            if (et.equalsIgnoreCase(fileType)) {
                return "p";
            }
        }
        for (String et : pdfExts) {
            if (et.equalsIgnoreCase(fileType)) {
                return "f";
            }
        }
        return null;
    }

    public static String getTypeCode(String fileType) {
        if ("word".equalsIgnoreCase(fileType)) {
            return "w";
        }
        if ("excel".equalsIgnoreCase(fileType)) {
            return "s";
        }
        if ("ppt".equalsIgnoreCase(fileType)) {
            return "p";
        }
        return null;
    }

    public static boolean checkCode(String fileType) {
        for (String et : office) {
            if (et.equalsIgnoreCase(fileType)) {
                return true;
            }
        }
        return false;
    }
}
